package ngamejava2;

import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Iterator;
import java.util.List;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class GameObjectContainer<C extends GameObjectContainer, T extends GameObject> extends GameObject<C>
{
	private ArrayDeque<T> objects;
	private Iterator<T> iterator;
	private T currentObject;

	public GameObjectContainer()
	{
		objects = new ArrayDeque<T>();
	}

	public void add(T anObject)
	{
		objects.addLast(anObject);
		anObject.setParent(this);
	}

	public void remove(T anObject)
	{
		objects.remove(anObject);
		anObject.setParent(null);
	}

	public void removeAll(List<T> someObjects)
	{
		objects.removeAll(someObjects);
		for (GameObject go : someObjects)
		{
			go.setParent(null);
		}
	}

	public void brintToFront(T anObject)
	{
		objects.remove(anObject);
		objects.addLast(anObject);
	}

	public void sendToBack(T anObject)
	{
		objects.remove(anObject);
		objects.addFirst(anObject);
	}

	public void resetIterator()
	{
		iterator = objects.iterator();
	}

	public boolean iteratorHasNext()
	{
		if (iterator.hasNext())
		{
			currentObject = iterator.next();
			return true;
		}
		else
		{
			return false;
		}
	}

	public T getCurrentObject()
	{
		return currentObject;
	}

	@Override
	public void write(GameWriter gw) throws IOException
	{
		super.write(gw);
		int i=0;
		for (T obj : objects)
		{
			gw.write("obj" + i++, obj);
		}
	}

	@Override
	public void read(GameReader gr, Node containerNode) throws XPathExpressionException
	{
		try
		{
			super.read(gr, containerNode);
			NodeList list = gr.readObjectList(containerNode, "child::object");
			objects.clear();
			for (int i=0; i<list.getLength(); i++)
			{
				Node objectNode = list.item(i);
				add((T)gr.readObject(objectNode));
			}
		}
		catch(InstantiationException ie)
		{
			throw new RuntimeException(ie);
		}
		catch(IllegalAccessException ie)
		{
			throw new RuntimeException(ie);
		}
		catch(ClassNotFoundException ie)
		{
			throw new RuntimeException(ie);
		}
	}
}